package bsts.controller;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;

import javax.swing.JFrame;

import bsts.application.BSTSApplication;
import bsts.model.Account;
import bsts.model.Customer;
import bsts.model.Feature;
import bsts.model.Subscription;
import bsts.view.bill.ManageBillWindow;
import bsts.view.complaint.AddComplaintFrm;
import bsts.view.complaint.ViewComplaintsFrm;
import bsts.view.customer.AddCustomerWindow;
import bsts.view.customer.AcctManageWindow;
import bsts.view.customer.ViewCustomersWindow;
import bsts.view.customer.ViewUpdCustomerWindow;
import bsts.view.subscription.NewSubscriptionWindow;
import bsts.view.subscription.UpdSubAddFeatureWindow;
import bsts.view.subscription.UpdSubscriptionWindow;
import bsts.view.subscription.ViewCustomerAccountsWindow;
import bsts.view.subscription.ViewCustomersWindowForSubscription;
import bsts.view.transaction.ViewTransactionsFrm;
import bsts.view.user.LoginWindow;
import bsts.view.user.MainWindow;

public class ViewController {

	private BSTSApplication manager;
	private LoginWindow loginWindow;
	private MainWindow mainWindow;
	private AddCustomerWindow addCustomerWindow;
	private ViewCustomersWindow viewCustomersWindow;
	private ViewUpdCustomerWindow viewUpdCustomerWindow;
	private AcctManageWindow acctManageWindow;
	private AddComplaintFrm addComplaintWindow;
	private ViewComplaintsFrm viewComplaintsWindow;
	private ManageBillWindow manageBillWindow;
	private NewSubscriptionWindow newSubscriptionWindow;
	private UpdSubscriptionWindow updSubscriptionWindow;
	private UpdSubAddFeatureWindow updSubAddFeatureWindow;
	private ViewTransactionsFrm viewTranscationsWindow;

	private ViewCustomersWindowForSubscription viewCustomersWindowForSubscription;
	private ViewCustomerAccountsWindow viewCustomerAccountsWindow;

	private boolean subscriptionCreateSelected = false;

	private static final Dimension DIM_LOGINWINDOW = new Dimension(440, 180);
	private static final Dimension DIM_MAINWINDOW = new Dimension(440, 400);
	private static final Dimension DIM_ADDCUSTOMERWINDOW = new Dimension(860,
			360);
	private static final Dimension DIM_VIEWCUSTOMERWINDOW = new Dimension(620,
			360);
	private static final Dimension DIM_VIEWUPDCUSTOMERWINDOW = new Dimension(
			880, 360);
	private static final Dimension DIM_ACCTMANAGEWINDOW = new Dimension(880,
			360);
	private static final Dimension DIM_MANAGEBILLWINDOW = new Dimension(600,
			400);
	private static final Dimension DIM_NEWSUBSCRIPTIONWINDOW = new Dimension(
			780, 460);
	private static final Dimension DIM_UPDSUBSCRIPTIONWINDOW = new Dimension(
			920, 400);
	private static final Dimension DIM_UPDSUBADDFEATUREWINDOW = new Dimension(
			800, 250);
	private static final Dimension DIM_VIEWCUSTOMERACCOUNTSWINDOW = new Dimension(
			420, 200);

	public ViewController(BSTSApplication manager) {
		this.manager = manager;
	}

	private LoginWindow getLoginWindow() {
		if (loginWindow != null)
			return loginWindow;

		loginWindow = new LoginWindow(manager);
		loginWindow.setSize(DIM_LOGINWINDOW);
		centerWindow(loginWindow);
		return loginWindow;
	}

	private MainWindow getMainWindow() {
		if (mainWindow != null)
			return mainWindow;

		mainWindow = new MainWindow(manager);
		mainWindow.setSize(DIM_MAINWINDOW);
		centerWindow(mainWindow);
		return mainWindow;
	}

	private void disposeMainWindow() {
		if (mainWindow != null) {
			mainWindow.dispose();
			mainWindow = null;
		}
	}

	private AddCustomerWindow getAddCustomerWindow() {
		if (addCustomerWindow != null)
			return addCustomerWindow;

		addCustomerWindow = new AddCustomerWindow(manager);
		addCustomerWindow.setSize(DIM_ADDCUSTOMERWINDOW);
		centerWindow(addCustomerWindow);
		return addCustomerWindow;
	}

	private void disposeAddCustomerWindow() {
		if (addCustomerWindow != null) {
			addCustomerWindow.dispose();
			addCustomerWindow = null;
		}
	}

	private ViewCustomersWindow getViewCustomersWindow() {
		if (viewCustomersWindow != null)
			return viewCustomersWindow;

		viewCustomersWindow = new ViewCustomersWindow(manager);
		viewCustomersWindow.setSize(DIM_VIEWCUSTOMERWINDOW);
		centerWindow(viewCustomersWindow);
		return viewCustomersWindow;
	}

	private void disposeViewCustomersWindow() {
		if (viewCustomersWindow != null) {
			viewCustomersWindow.dispose();
			viewCustomersWindow = null;
		}
	}

	private ViewUpdCustomerWindow getViewUpdCustomerWindow(JFrame parent,
			Customer customer) {
		disposeViewUpdCustomerWindow();

		viewUpdCustomerWindow = new ViewUpdCustomerWindow(manager, parent,
				customer);
		viewUpdCustomerWindow.setSize(DIM_VIEWUPDCUSTOMERWINDOW);
		centerWindow(viewUpdCustomerWindow);
		return viewUpdCustomerWindow;
	}

	private void disposeViewUpdCustomerWindow() {
		if (viewUpdCustomerWindow != null) {
			viewUpdCustomerWindow.dispose();
			viewUpdCustomerWindow = null;
		}
	}

	private AcctManageWindow getAcctManageWindow(JFrame parent,
			Customer customer) {
		if (acctManageWindow != null)
			acctManageWindow.dispose();

		acctManageWindow = new AcctManageWindow(manager, parent, customer);
		acctManageWindow.setSize(DIM_ACCTMANAGEWINDOW);
		centerWindow(acctManageWindow);
		return acctManageWindow;
	}

	private void disposeAcctManageWindow() {
		if (acctManageWindow != null) {
			acctManageWindow.dispose();
			acctManageWindow = null;
		}
	}

	private AddComplaintFrm getAddComplaintWindow() {
		if (addComplaintWindow != null)
			addComplaintWindow.dispose();

		addComplaintWindow = new AddComplaintFrm("Log Complaint", 600, 350,
				manager);
		addComplaintWindow.setSize(600, 350);
		centerWindow(addComplaintWindow);
		return addComplaintWindow;
	}

	private ViewComplaintsFrm getViewComplaintsWindow() {
		if (viewComplaintsWindow != null)
			viewComplaintsWindow = null;

		viewComplaintsWindow = new ViewComplaintsFrm();
		return viewComplaintsWindow;
	}

	private ManageBillWindow getManageBillWindow() {
		if (manageBillWindow != null)
			manageBillWindow = null;

		manageBillWindow = new ManageBillWindow(manager);
		manageBillWindow.setSize(DIM_MANAGEBILLWINDOW);
		manageBillWindow.refresh();
		centerWindow(manageBillWindow);
		return manageBillWindow;
	}

	private void disposeManageBillWindow() {
		if (manageBillWindow != null) {
			manageBillWindow.dispose();
			manageBillWindow = null;
		}
	}

	private NewSubscriptionWindow getNewSubscriptionWindow(JFrame container,
			Account account, Customer customer) {
		if (newSubscriptionWindow != null)
			newSubscriptionWindow = null;

		newSubscriptionWindow = new NewSubscriptionWindow(manager, container,
				account, customer);
		newSubscriptionWindow.setSize(DIM_NEWSUBSCRIPTIONWINDOW);
		centerWindow(newSubscriptionWindow);
		return newSubscriptionWindow;
	}

	private void disposeNewSubscriptionWindow() {
		if (newSubscriptionWindow != null) {
			newSubscriptionWindow.dispose();
			newSubscriptionWindow = null;
		}
	}

	private UpdSubscriptionWindow getUpdSubscriptionWindow(JFrame container, Account account,
			Customer customer) {
		if (updSubscriptionWindow != null)
			disposeUpdSubscriptionWindow();

		updSubscriptionWindow = new UpdSubscriptionWindow(manager, container, account,
				customer);
		updSubscriptionWindow.setSize(DIM_UPDSUBSCRIPTIONWINDOW);
		centerWindow(updSubscriptionWindow);
		return updSubscriptionWindow;
	}

	private void disposeUpdSubscriptionWindow() {
		if (updSubscriptionWindow != null) {
			updSubscriptionWindow.dispose();
			updSubscriptionWindow = null;
		}
	}

	private UpdSubAddFeatureWindow getUpdSubAddFeatureWindow(JFrame parent,
			ArrayList<Feature> availableFeatures,
			ArrayList<Feature> selectedFeatures, Subscription subscription,
			Account account, Customer customer) {
		if (updSubAddFeatureWindow != null)
			disposeUpdSubAddFeatureWindow();

		updSubAddFeatureWindow = new UpdSubAddFeatureWindow(manager, parent,
				availableFeatures, selectedFeatures, subscription, account,
				customer);
		updSubAddFeatureWindow.setSize(DIM_UPDSUBADDFEATUREWINDOW);
		centerWindow(updSubAddFeatureWindow);
		return updSubAddFeatureWindow;
	}

	private void disposeUpdSubAddFeatureWindow() {
		if (updSubAddFeatureWindow != null) {
			updSubAddFeatureWindow.dispose();
			updSubAddFeatureWindow = null;
		}

	}
	
	private ViewTransactionsFrm getViewTransactionsWindow() {
		if (viewTranscationsWindow != null)
			disposeViewTransactionsWindow();
		
		viewTranscationsWindow = new ViewTransactionsFrm();
		centerWindow(viewTranscationsWindow);
		return viewTranscationsWindow;
	}
	
	private void disposeViewTransactionsWindow() {
		if (viewTranscationsWindow != null) {
			viewTranscationsWindow.dispose();
			viewTranscationsWindow = null;
		}
	}

	// end of get & dispose window

	public void goBackMain(JFrame curr) {
		mainWindow.setEnabled(true);
		mainWindow.requestFocus();
		disposeWindow(curr);
	}

	public void goBackParent(JFrame parent, JFrame me) {
		parent.setEnabled(true);
		parent.requestFocus();

		if (((parent instanceof ViewCustomersWindow) && (me instanceof AcctManageWindow))
				|| ((parent instanceof ViewCustomersWindow) && (me instanceof ViewUpdCustomerWindow))) {
			disposeWindow(me);
			disposeWindow(parent);
			showViewCustomersWindow(manager);
		} else {
			disposeWindow(me);
		}
	}

	public void goBackUpdSubscriptionWindow(JFrame parent, JFrame me,
			Account account, Customer customer) {
		parent.setEnabled(true);
		parent.requestFocus();

		disposeWindow(me);
		disposeWindow(parent);
		showUpdSubscriptionWindow(parent, account, customer);
	}

	public void showLoginWindow() {
		getLoginWindow().setVisible(true);
	}

	public void hideLoginWindow() {
		loginWindow.setVisible(false);
	}

	public void showMainwindow(BSTSApplication bstsApplication) {
		getMainWindow().setVisible(true);
	}

	public void showAddCustomerWindow(BSTSApplication bstsApplication) {
		mainWindow.setEnabled(false);
		getAddCustomerWindow().setVisible(true);
	}

	public void showViewCustomersWindow(BSTSApplication bstsApplication) {
		mainWindow.setEnabled(false);
		getViewCustomersWindow().setVisible(true);
	}

	public void showViewCustomerWindow(BSTSApplication bstsApplication,
			JFrame me, Customer customer) {
		mainWindow.setEnabled(false);
		me.setEnabled(false);
		getViewUpdCustomerWindow(me, customer).setVisible(true);
	}

	public void showManageBillWindow() {
		mainWindow.setEnabled(false);
		getManageBillWindow().setVisible(true);
	}

	// /////////////////////////////////////////////////////////////////////////////

	private ViewCustomerAccountsWindow getViewCustomerAccountsWindow(
			JFrame parent, Customer customer) {
		disposeViewCustomerAccountsWindow();

		viewCustomerAccountsWindow = new ViewCustomerAccountsWindow(manager,
				parent, customer);
		viewCustomerAccountsWindow.setSize(DIM_VIEWCUSTOMERACCOUNTSWINDOW);
		centerWindow(viewCustomerAccountsWindow);

		return viewCustomerAccountsWindow;
	}

	private void disposeViewCustomerAccountsWindow() {
		if (viewCustomerAccountsWindow != null) {
			viewCustomerAccountsWindow.dispose();
			viewCustomerAccountsWindow = null;
		}
	}

	public void showViewCustomerAccountsWindow(BSTSApplication bstsApplication,
			JFrame me, Customer customer) {
		mainWindow.setEnabled(false);
		me.setEnabled(false);
		getViewCustomerAccountsWindow(me, customer).setVisible(true);
	}

	private ViewCustomersWindowForSubscription getViewCustomersWindowForSubscription() {
		if (viewCustomersWindowForSubscription != null)
			return viewCustomersWindowForSubscription;

		viewCustomersWindowForSubscription = new ViewCustomersWindowForSubscription(
				manager);
		viewCustomersWindowForSubscription.setSize(DIM_VIEWCUSTOMERWINDOW);
		centerWindow(viewCustomersWindowForSubscription);
		return viewCustomersWindowForSubscription;
	}

	private void disposeViewCustomersWindowForSubscription() {
		if (viewCustomersWindowForSubscription != null) {
			viewCustomersWindowForSubscription.dispose();
			viewCustomersWindowForSubscription = null;
		}
	}

	public void showViewCustomersWindowForSubscriptions() {
		mainWindow.setEnabled(false);
		getViewCustomersWindowForSubscription().setVisible(true);
	}

	public void setSubscriptionCreateSelectionStatus() {
		subscriptionCreateSelected = true;
	}

	public void setSubscriptionUpdateSelectionStatus() {
		subscriptionCreateSelected = false;
	}

	public boolean getSubscriptionCreate() {
		return subscriptionCreateSelected;
	}

	// /////////////////////////////////////////////////////////////////////////////

	public void showNewSubscriptionWindow(JFrame container, Account account,
			Customer customer) {
		mainWindow.setEnabled(false);
		container.setEnabled(false);
		getNewSubscriptionWindow(container, account, customer).setVisible(true);
	}

	public void showUpdSubscriptionWindow(JFrame container, Account account, Customer customer) {
		mainWindow.setEnabled(false);
		container.setEnabled(false);
		getUpdSubscriptionWindow(container, account, customer).setVisible(true);
	}

	public void showUpdSubAddFeatureWindow(JFrame container,
			ArrayList<Feature> availableFeatures,
			ArrayList<Feature> selectedFeatures, Subscription subscription,
			Account account, Customer customer) {
		mainWindow.setEnabled(false);
		container.setEnabled(false);
		getUpdSubAddFeatureWindow(container, availableFeatures,
				selectedFeatures, subscription, account, customer).setVisible(
				true);
	}

	public void showAcctManageWindow(BSTSApplication bstsApplication,
			JFrame me, Customer customer) {
		me.setEnabled(false);
		getAcctManageWindow(me, customer).setVisible(true);
	}

	public void showAddComplaintWindow() {
		getAddComplaintWindow().setVisible(true);
	}

	public void showViewComplaintsWindow() {
		getViewComplaintsWindow().setVisible(true);
	}
	
	public void showViewTransactionsWindow() {
		getViewTransactionsWindow().setVisible(true);
	}

	public void disposeUserWindows() {
		disposeMainWindow();
		disposeAddCustomerWindow();
		disposeViewCustomersWindow();
		disposeViewUpdCustomerWindow();
		disposeAcctManageWindow();
		disposeManageBillWindow();
		disposeNewSubscriptionWindow();
		disposeUpdSubscriptionWindow();
		disposeUpdSubAddFeatureWindow();
		disposeViewTransactionsWindow();

		disposeViewCustomerAccountsWindow();
		disposeViewCustomersWindowForSubscription();
	}

	private void disposeWindow(JFrame window) {
		if (window instanceof MainWindow)
			disposeMainWindow();
		else if (window instanceof AddCustomerWindow)
			disposeAddCustomerWindow();
		else if (window instanceof ViewCustomersWindow)
			disposeViewCustomersWindow();
		else if (window instanceof ViewUpdCustomerWindow)
			disposeViewUpdCustomerWindow();
		else if (window instanceof AcctManageWindow)
			disposeAcctManageWindow();
		else if (window instanceof ManageBillWindow)
			disposeManageBillWindow();
		else if (window instanceof NewSubscriptionWindow)
			disposeNewSubscriptionWindow();
		else if (window instanceof UpdSubscriptionWindow)
			disposeUpdSubscriptionWindow();
		else if (window instanceof UpdSubAddFeatureWindow)
			disposeUpdSubAddFeatureWindow();
		else if (window instanceof ViewCustomerAccountsWindow)
			disposeViewCustomerAccountsWindow();
		else if (window instanceof ViewCustomersWindowForSubscription)
			disposeViewCustomersWindowForSubscription();
		else if (window instanceof ViewTransactionsFrm)
			disposeViewTransactionsWindow();
	}

	private void centerWindow(JFrame inputWindow) {
		// Center the window
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Dimension frameSize = inputWindow.getSize();

		if (frameSize.height > screenSize.height) {
			frameSize.height = screenSize.height;
		}

		if (frameSize.width > screenSize.width) {
			frameSize.width = screenSize.width;
		}

		inputWindow.setLocation((screenSize.width - frameSize.width) / 2,
				(screenSize.height - frameSize.height) / 2);
	}

}
